package engine.systems.render.reflection
{
	import ash.core.Engine;
	import ash.core.NodeList;
	import ash.core.System;
	
	import engine.classes.enumerations.Direction;
	import engine.classes.enumerations.SystemPriority;
	import engine.utils.DisplayUtils;
	import engine.utils.EntityUtils;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	public class ReflectionSystem extends System
	{
		private var reflections:NodeList;
		private var reflectives:NodeList;
		
		//private var point:Point = new Point();
		
		//public var sortWaitTime:Number;
		//private var sortElapsedTime:Number = 0;
		
		public function ReflectionSystem()
		{
			//this.sortWaitTime = sortWaitTime;
			this.priority = SystemPriority.POST_RENDER;
		}
		
		override public function update(time:Number):void
		{
			//this.sortElapsedTime += time;
			//if(this.sortElapsedTime >= this.sortWaitTime)
			//{
				//this.sortElapsedTime = 0;
				//this.reflections.insertionSort(this.sortByIndex);
			//}
			
			/*for(var reflectiveNode:ReflectiveNode = this.reflectives.head; reflectiveNode; reflectiveNode = reflectiveNode.next)
			{
				if(EntityUtils.sleeping(reflectiveNode.entity)) continue;
				
				var reflective:Reflective = reflectiveNode.reflective;
				var bitmap:Bitmap = reflectiveNode.render.display as Bitmap;
				
				reflective.elapsedTime += time;
				if(reflective.elapsedTime < reflective.waitTime) continue;
				reflective.elapsedTime = 0;
				
				var data:BitmapData = bitmap.bitmapData;
				data.fillRect(data.rect, 0);
				
				var reflectionNode:ReflectionNode;
				var reflection:Reflection;
				var display:DisplayObject;
				var matrix:Matrix;
				
				switch(reflective.direction)
				{
					case Direction.BACKWARD:
					case Direction.FORWARD:
						for(reflectionNode = this.reflections.tail; reflectionNode; reflectionNode = reflectionNode.previous)
						{
							if(EntityUtils.sleeping(reflectionNode.entity)) continue;
							
							reflection = reflectionNode.reflection;
							if(!reflection.types[reflective.type]) continue;
							
							display = reflectionNode.render.display;
							
							this.point = DisplayUtils.localToLocal(display.x, display.y, display.parent, bitmap.parent);
							
							matrix = display.transform.matrix;
							matrix.scale(1, 1);
							matrix.tx = (point.x - bitmap.x) + reflection.offsetX;
							matrix.ty = (point.y - bitmap.y) + reflection.offsetY;
							
							data.draw(display, matrix, reflection.colorTransform, reflection.blendMode, reflection.clipRect);
						}
						break;
					
					case Direction.UP:
						for(reflectionNode = this.reflections.head; reflectionNode; reflectionNode = reflectionNode.next)
						{
							if(EntityUtils.sleeping(reflectionNode.entity)) continue;
							
							reflection = reflectionNode.reflection;
							if(!reflection.types[reflective.type]) continue;
							
							display = reflectionNode.render.display;
							
							this.point = DisplayUtils.localToLocal(display.x, display.y, display.parent, bitmap.parent);
							
							matrix = display.transform.matrix;
							matrix.scale(1, -1);
							matrix.tx = (point.x - bitmap.x) + reflection.offsetX;
							matrix.ty = (data.height * 2) + (bitmap.y - point.y) + reflection.offsetY;
							
							data.draw(display, matrix, reflection.colorTransform, reflection.blendMode, reflection.clipRect);
						}
						break;
					
					case Direction.DOWN:
						for(reflectionNode = this.reflections.head; reflectionNode; reflectionNode = reflectionNode.next)
						{
							if(EntityUtils.sleeping(reflectionNode.entity)) continue;
							
							reflection = reflectionNode.reflection;
							if(!reflection.types[reflective.type]) continue;
							
							display = reflectionNode.render.display;
							
							this.point = DisplayUtils.localToLocal(display.x, display.y, display.parent, bitmap.parent);
							
							matrix = display.transform.matrix;
							matrix.scale(1, -1);
							matrix.tx = (point.x - bitmap.x) + reflection.offsetX;
							matrix.ty = (bitmap.y - point.y) + reflection.offsetY;
							
							data.draw(display, matrix, reflection.colorTransform, reflection.blendMode, reflection.clipRect);
						}
						break;
					
					case Direction.LEFT:
						for(reflectionNode = this.reflections.tail; reflectionNode; reflectionNode = reflectionNode.previous)
						{
							if(EntityUtils.sleeping(reflectionNode.entity)) continue;
							
							reflection = reflectionNode.reflection;
							if(!reflection.types[reflective.type]) continue;
							
							display = reflectionNode.render.display;
							
							this.point = DisplayUtils.localToLocal(display.x, display.y, display.parent, bitmap.parent);
							
							matrix = display.transform.matrix;
							matrix.scale(-1, 1);
							matrix.tx = (data.width * 2) - (point.x - bitmap.x) + reflection.offsetX;
							matrix.ty = (point.y - bitmap.y) + reflection.offsetY;
							
							data.draw(display, matrix, reflection.colorTransform, reflection.blendMode, reflection.clipRect);
						}
						break;
					
					case Direction.RIGHT:
						for(reflectionNode = this.reflections.tail; reflectionNode; reflectionNode = reflectionNode.previous)
						{
							if(EntityUtils.sleeping(reflectionNode.entity)) continue;
							
							reflection = reflectionNode.reflection;
							if(!reflection.types[reflective.type]) continue;
							
							display = reflectionNode.render.display;
							
							this.point = DisplayUtils.localToLocal(display.x, display.y, display.parent, bitmap.parent);
							
							matrix = display.transform.matrix;
							matrix.scale(-1, 1);
							matrix.tx = (bitmap.x - point.x) + reflection.offsetX;
							matrix.ty = (point.y - bitmap.y) + reflection.offsetY;
							
							data.draw(display, matrix, reflection.colorTransform, reflection.blendMode, reflection.clipRect);
						}
						break;
				}
			}*/
		}
		
		override public function addToEngine(systemManager:Engine):void
		{
			//this.reflections = systemManager.getNodeList(ReflectionNode);
			//this.reflectives = systemManager.getNodeList(ReflectiveNode);
			
			//this.reflections.insertionSort(this.sortByIndex);
			//this.reflections.nodeAdded.add(this.nodeAdded);
		}
		
		override public function removeFromEngine(systemManager:Engine):void
		{
			//systemManager.releaseNodeList(ReflectionNode);
			//systemManager.releaseNodeList(ReflectiveNode);
			
			//this.reflections = null;
			//this.reflectives = null;
		}
		
		private function nodeAdded(node:ReflectionNode):void
		{
			//this.reflections.insertionSort(this.sortByIndex);
		}
		
		/**
		 * SortByIndex() is used to sort what Display Objects are in front/back of others so they can be drawn to
		 * the Reflective surface in order of depth. We don't want to be doing this all the time though.
		 */
		
		/**
		 * Currently this system assumes that all Reflection Nodes are in the same Display Object Container.
		 * Will need to fix this later.
		 */
		private function sortByIndex(node1:ReflectionNode, node2:ReflectionNode):Number
		{
			var index1:int = node1.render.display.parent.getChildIndex(node1.render.display);
			var index2:int = node2.render.display.parent.getChildIndex(node2.render.display);
			
			return (index1 < index2) ? -1 : 1;
		}
	}
}